import React, { useState, useEffect } from 'react';
import TjTable from '@/pages/ETrade/components/TjTable';
import { TjForm } from '@/tjComponents';
import { DatePicker, Select } from 'antd';
import { useForm } from 'antd/es/form/Form';
import { useSetState } from 'ahooks';
import { queryDataByDay } from '../../service';
import { HttpCode } from '#/utils/contacts.js';
import { buildAddTable } from '../../helper';
import np from '@/utils/numberPrecision';
import _ from 'lodash';
import moment from 'moment';
import type { ArtColumn } from 'ali-react-table';
import type { StationType } from '@/hooks/useRequestPowerAfterInit';
import type { Moment } from 'moment';

import './index.less';

const { RangePicker } = DatePicker;

const AddModal: React.FC<IAddModalProps> = (props) => {
  const [req, setReq] = useSetState<any>({});
  const [form] = useForm();
  const [loading, setLoading] = useState<boolean>(false);
  const [columns, setColumns] = useState<ArtColumn[]>([]);
  const [dataSource, setDataSource] = useState<any[]>([]);
  const [dates, setDates] = useState<[Moment | null, Moment | null]>([null, null]);

  const query = () => {
    setLoading(true);
    const newReq = {
      ...req,
    };
    if (req.time) {
      newReq.startDate = moment(req.time[0]).format('YYYY-MM-DD');
      newReq.endDate = moment(req.time[1]).format('YYYY-MM-DD');
      delete newReq.time;
    }
    newReq.stationIds = [newReq.stationIds];
    queryDataByDay(newReq)
      .then((res: any) => {
        if (res.statusCode === HttpCode.SUCCESS) {
          if (dataSource.length > 0) {
            const dataList: any = {};
            dataSource.forEach((v, i) => {
              dataList[`dataList@${i}`] = undefined;
            });
            form.setFieldsValue(dataList);
          }

          const obj = buildAddTable(res.data.head, res.data.dataList);
          setColumns(obj.columns);
          setDataSource(obj.dataSource);
          // retrieveData(dataSource);
        }
      })
      .finally(() => {
        setLoading(false);
      });
  };

  const retrieveData = (dataSource: any[]) => {
    const formData: any = {};
    const lastAmount: any = {};

    for (let i = 0; i < dataSource.length; i++) {
      const row = dataSource[i];
      if (i === dataSource.length - 1) {
        formData[`dataList@${i}`] = _.mapValues(lastAmount, (value: any) =>
          value === 0 ? undefined : value,
        );
      } else {
        const obj: any = {};
        const nums = [];
        for (const o in row) {
          if (o !== 'date') {
            if (row[o] || row[o] === 0) {
              obj[o] = row[o];
              nums.push(row[o]);

              if (!lastAmount[o]) {
                lastAmount[o] = 0;
              }
              lastAmount[o] = np.plus(lastAmount[o], row[o]);
            } else {
              obj[o] = undefined;
            }
          }
        }
        const sum = np.plus(...nums);
        obj.sum = sum ? sum : undefined;
        formData[`dataList@${i}`] = obj;
      }
    }
    form.setFieldsValue(formData);
  };

  const getAmount = _.debounce((obj: any) => {
    const newData: any = {};
    const lastAmount: any = {};
    const lastIndex = dataSource.length - 1;
    for (const k in obj) {
      if (k.indexOf('@') > -1) {
        const index = k.split('@')[1];
        if (Number(index) !== lastIndex) {
          const nums: any[] = [];
          const row = _.omit(obj[k], ['sum']);
          for (const r in row) {
            const num = row[r] ? row[r] : 0;
            nums.push(num);
            if (!lastAmount[r]) {
              lastAmount[r] = 0;
            }
            lastAmount[r] = np.plus(lastAmount[r], num);
          }
          const rowAmount = np.plus(...nums);
          newData[k] = {
            sum: rowAmount !== 0 ? rowAmount : undefined,
          };
        }
        if (Number(index) === lastIndex) {
          newData[k] = _.mapValues(lastAmount, (value: any) => (value === 0 ? undefined : value));
        }
      }
    }
    form.setFieldsValue(newData);
  }, 300);

  const onValuesChange = (changedValues: any, values: any) => {
    if (changedValues.time || changedValues.stationIds) {
      setReq(changedValues);
    }
    const key = Object.keys(changedValues);
    if (key[0].indexOf('@') > -1) {
      getAmount(values);
    }
  };

  const disabledDate = (current: Moment) => {
    if (!dates || (!dates[0] && !dates[1])) {
      return false;
    }
    const tooLate = dates[0] && current.diff(dates[0], 'months') !== 0;
    const tooEarly = dates[1] && dates[1].diff(current, 'months') !== 0;
    return !!tooEarly || !!tooLate;
  };

  useEffect(() => {
    props.getHandler &&
      props.getHandler(() => {
        return new Promise((resolve, reject) => {
          form
            .validateFields()
            .then((values: any) => {
              const newData: any = {
                stationId: values.stationIds,
                list: [],
              };
              const lastIndex = dataSource.length - 1;

              for (const k in values) {
                if (k.indexOf('@') > -1) {
                  const index = k.split('@')[1];
                  if (lastIndex !== Number(index)) {
                    const row: any = {
                      ..._.omitBy(_.omit(values[k], ['sum']), _.isNil),
                      date: dataSource[Number(index)].date,
                    };
                    if (Object.keys(row).length > 1) {
                      newData.list.push(row);
                    }
                  }
                }
              }
              resolve(newData);
            })
            .catch((values: any) => {
              reject(values);
            });
        });
      });
  });

  useEffect(() => {
    if (props.currentReq) {
      const obj = {
        time: props.currentReq.time,
        stationIds: props.currentReq.stationIds[0],
      };
      setReq(obj);
      form.setFieldsValue(obj);
    }
  }, [props.currentReq]);

  useEffect(() => {
    if (req.stationIds) {
      query();
    }
  }, [req]);

  useEffect(() => {
    retrieveData(dataSource);
  }, [dataSource]);

  return (
    <div className="add-modal">
      <TjForm
        form={form}
        items={[
          {
            label: '日期',
            name: 'time',
            render: (
              <RangePicker
                onCalendarChange={(val) => setDates(val as any)}
                disabledDate={disabledDate}
              />
            ),
          },
          {
            label: '交易单元',
            name: 'stationIds',
            render: (
              <Select loading={loading}>
                {props.currentStations &&
                  props.currentStations.map((item) => (
                    <Select.Option key={item.stationId} value={item.stationId}>
                      {item.stationName}
                    </Select.Option>
                  ))}
              </Select>
            ),
          },
          {
            // name: 'dataList',
            render: (
              <div className="table-box">
                <TjTable
                  columns={columns}
                  dataSource={dataSource}
                  primaryKey={'date'}
                  isLoading={loading}
                />
              </div>
            ),
            wrapperCol: { span: 24 },
          },
        ]}
        onValuesChange={onValuesChange}
      />
    </div>
  );
};

interface IAddModalProps {
  currentStations?: StationType[];
  currentReq: Record<string, any>;
  getHandler?: (fn: () => Promise<any>) => void;
}

export default AddModal;
